package IO;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

/**
 *  //步骤:
 *  1) 创建字符输入流对象，关联数据源文件(建议第一步就抛出父类异常IOException)
 *  2) 定义变量，记录读取到的内容
 *  3) 循环读取，只要条件满足就一直读，并将读取到的内容赋值给变量
 *  4) 释放资源。（为防止遗忘，最好先释放资源。）
 *  //读取方法：
 *  char[] charArray = new char[3];   //定义了一个初始长度为3的字符数组
 *  int data = reader.read(charArray);
 *
 */

public class ArrayCharacter {
    public static void main(String[] args) throws IOException {

        //1.创建字符输入流对象，关联数据源文件（建议第一步就抛出父类异常IOException）
        Reader reader = new FileReader("D:\\code\\2.txt");
        //2.txt 文件中自己输入内容，这里测试我输入的是 “我口袋只剩玫瑰一片，此行山高又路远”
        //2.定义变量，记录读取到的内容
        char[] charArray = new char[3];   //定义了一个初始长度为3 的字符数组
        int i1 = reader.read(charArray);//第一次读取
        /*
            字符串的底层，其实就是一个字符数组，所以此处会将字符数组中的内容自动拼接成字符串
         */
        System.out.println("第一次读取：");
        System.out.println(charArray);
        System.out.println("第一次读取到的有效字符数是：" + i1);     //有效字符数3
        System.out.println("--------------------------");

        int i2 = reader.read(charArray);//第二次读取
        System.out.println("第二次读取：");
        System.out.println(charArray);
        System.out.println("第二次读取到的有效字符数是：" + i2);     //有效字符数3
        System.out.println("--------------------------");

        int i3 = reader.read(charArray);//第三次读取
        System.out.println("第三次读取：");
        System.out.println(charArray);
        System.out.println("第三次读取到的有效字符数是：" + i3);     //有效字符数3
        System.out.println("--------------------------");

        int i4 = reader.read(charArray);//第四次读取
        System.out.println("第四次读取：");
        System.out.println(charArray);
        System.out.println("第四次读取到的有效字符数是：" + i4);     //有效字符数3
        System.out.println("--------------------------");

        int i5 = reader.read(charArray);//第五次读取
        System.out.println("第五次读取：");
        System.out.println(charArray);
        System.out.println("第五次读取到的有效字符数是：" + i5);     //有效字符数3
        System.out.println("--------------------------");

        int i6 = reader.read(charArray);//第六次读取
        System.out.println("第六次读取：");
        System.out.println(charArray);
        System.out.println("第六次读取到的有效字符数是：" + i6);     //有效字符数1
        System.out.println("=========================================");
        /*
                发现没有? 第六次用charArray这个数组来读时，输出结果为”路远又“
            ，而且有效字符数是1，这说明每次3个3个的读取，其实本质是将读取到
            的内容覆盖掉数组中原本的内容。
                但因为我们创建的2.txt文本文件中，一共16个字符，17 / 3 = 5······2，
            所以第六次读取时，只读到了"路远",但是输出的却是“路远又”
         */

        /*
            用While循环优化以上代码；
        */
        System.out.println("我们可以发现，下面的while循环并没有执行，为啥？？？");
        System.out.println("=====================================");
        //同一个字符输入流读文件对象 在读取文件时是一定的，即读到哪儿就算那儿，倘若已经读到了流的末尾，再读一遍就需要创建新的读文件对象了
        //所以，我们需要往 2.txt 文件中多输入一些内容
        //这里又补充了 大鹏一日同风起，扶摇直上九万里

        //这里再解释一下，为什么while循环读取时，读取的第一个数组，只有两个数据“大鹏”，但是读取数量却是3
        //这是因为，在 2.txt 输入时，两段内容之间用 enter键 隔开了，而在windows系统下，一个enter键包含着 \n\t 两个字符内容
        //所以在，上面的覆盖时，覆盖了 \n 但还剩下一个 \t 被while循环读取了  （这里不太明白也没事）


        //3.循环读取，只要条件满足就一直读，并将读取到的内容赋值给变量
        //定义一个变量，记录读取到的有效字符数
        int count = 0;
        while ((count = reader.read(charArray)) != -1) {
            /**
             可以将读取到的内容转换成字符串，并打印出来，这里利用了String的一个特别构造
             * */
            String charString = new String(charArray, 0, count);
            //String charString = new String(charArray);
            //如果用这个代码代替的话，最后输出结果是 “里九万”
            /*
             * 该构造方法需要传入字符数组名， 起始索引， 以及有效字符数(特别注意这个有效字符数)
             * String这个构造器中三个参数的作用————
             *   ①charArray : 表示要使用的数组（用这个数组来读取内容）
             *   ②0 : 表示起始索引
             *   ③len : 表示 要操作的字符 的个数
             *     注意:如果这里只传入数组名，那么控制台上打印出的效果会和原来一样————
             *     即，当文件中的剩余字符数小于既定数组长度时，能覆盖几个覆盖几个。
             * */
            System.out.println(charString);
            System.out.println(count);
        }
        //4.释放资源// 一定要记得释放
        reader.close();
    }
}
/**
 * 总结
 * ①利用字符输入流的r.read(字符数组);的方法按字符数组读取文件时，数组内的内容每次都会被
 * 重新覆盖(覆盖范围是既定的数组的长度) ，若剩余有效符数小于既定数组长度，则能覆盖几个覆盖几个
 * ，剩下的还是上次覆盖的内容。
 * ②空格对文件的影响还是很大的
 * ③同一个字符输入流读文件对象 在读取文件时是一定的，即读到哪儿就算那儿，倘若已经读到了流的末尾，
 * 再读一遍就需要创建新的读文件对象了，这是因为当前字符流相当于已经读完了。
 */
